<template>
  <div>
    <el-card body-style="padding:0px;margin:0px">
      <div class="flex-wrap">
        <div class="flex-wrap go-back" @click="handleClickBack">
          <img :src="backImg"/>
          <span style="margin-left: 10px">返回</span>
        </div>
        <div style="color:#00955b;font-weight:bolder;margin-left: 20px">添加地址</div>
      </div>
    </el-card>
    <div style="height:14px"/>
    <el-card :style="{height:mainCardHeight+'px'}">
      <div style="padding-right: 20px">
        <el-form :model="landForm" :rules="landRules" ref="landForm">
          <el-row>
            <el-col :span="12">
              <el-form-item label="种植人员" :label-width="formLabelWidth" prop="planter">
                <el-select v-model="landForm.planter" placeholder="请选择种植人员" clearable style="width:100%">
                  <el-option v-for="item in plantersTypeOptions" :key="item.planterCode" :label="item.planterName"
                             :value="item.planterCode"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="巡田人员" :label-width="formLabelWidth" prop="patrol">
                <el-select v-model="landForm.patrol" placeholder="请选择巡田人员" clearable style="width:100%">
                  <el-option v-for="item in patrolTypeOptions" :key="item.patrolCode" :label="item.patrolName"
                             :value="item.patrolCode"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="地块名称" :label-width="formLabelWidth" prop="landName">
                <el-input v-model.trim="landForm.landName" style="width:100%" placeholder="请输入地块名称"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="地块类型" :label-width="formLabelWidth" prop="landType">
                <el-select v-model="landForm.landType" placeholder="请选择地块类型" clearable style="width:100%">
                  <el-option v-for="item in landTypeOptions" :key="item.typeCode" :label="item.typeName"
                             :value="item.typeCode"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="地块面积" :label-width="formLabelWidth" prop="landArea">
                <el-input v-model.trim="landForm.landArea" style="width:100%" placeholder="请先遥感定位获取面积">
                  <span slot="append">亩</span>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="种植面积" :label-width="formLabelWidth" prop="area">
                <el-input v-model.trim="landForm.area" style="width:100%" placeholder="请先遥感定位获取面积">
                  <span slot="append">亩</span>
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="遥感定位" :label-width="formLabelWidth" prop="position">
            <div class="land-add-button" @click="handleClickMap"><img :src="landImg" />点击绘制地图轮廓</div>
          </el-form-item>
          <el-form-item label="地块预览" :label-width="formLabelWidth" prop="preview">
            <div class="land-preview-container" :style="{height:(mainCardHeight-310)+'px'}">
              <div :style="{height:(mainCardHeight-320)+'px',position:'relative'}" v-show="imageData==null">
                <img class="land-preview-img" :src="emptyImg"/>
                <div class="land-preview-text">待获取</div>
              </div>
              <canvas :style="{height:(mainCardHeight-320)+'px', width:'50%'}" class="canvas-wrap" id="target_map_canvas" v-show="imageData!=null"></canvas>
            </div>
          </el-form-item>
          <el-form-item>
            <div style="display: flex;width: 100%;align-items: center;justify-content: center;margin-top: 10px">
              <el-button type="primary" @click="onSubmit" :loading="saveStatus">&nbsp;&nbsp;&nbsp;&nbsp;保&nbsp;存&nbsp;&nbsp;&nbsp;&nbsp;</el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>
    </el-card>
    <el-dialog
      top="4vh"
      destroy-on-close
      :visible.sync="innerVisible"
      append-to-body>
      <div slot="title">
        <div style="color:#fff">地图定位</div>
      </div>
      <div id="mapLandDiv" style="height:680px;width:920px"/>
    </el-dialog>
  </div>
</template>
<script>
    import "ol/ol.css"
    import Fill from "ol/style/Fill"
    import Map from "ol/Map"
    import View from "ol/View"
    import {Vector, Tile as TileLayer} from "ol/layer"
    import {OSM, Vector as VectorSource} from "ol/source"
    import {GeoJSON} from "ol/format"
    import {Style, Stroke, Circle as CircleStyle} from "ol/style"
    import {fromLonLat, transformExtent} from "ol/proj"
    import {
        Select,
        DoubleClickZoom,
        DragPan,
        MouseWheelZoom,
        Draw, Modify, Snap
    } from "ol/interaction"
    import ImageWMS from "ol/source/ImageWMS"
    import Image from "ol/layer/Image"
    import { getArea } from 'ol/sphere'
    import { get} from 'ol/proj';
    import {
        getLandProperties
    } from '@/api/material'
    import {
        postFarmLand,
        queryPlanters,
        queryWatchPlanters
    } from "@/api/affairs"
    import {
        upload
    } from '@/api/upload'
  export default {
      data(){
          const validateArea = (rule, value, callback) => {
              if (value == null || value == '' || value == undefined) {
                  callback(new Error('种植面积不能为空'))
              } else {
                  const reg = /^([+]\d+[.]\d+|[-]\d+[.]\d+|\d+[.]\d+|[+]\d+|[-]\d+|\d+)$/gi　　　　　　//数字开始，数字结束
                  const dataArr = (this.landForm.area + "").match(reg)
                  if (dataArr == null || dataArr.length == 0) {
                      callback(new Error('种植面积格式错误'))
                  }
                  callback()
              }
          }
          const validatelandArea = (rule, value, callback) => {
              if (value == null || value == '' || value == undefined) {
                  callback(new Error('地块面积不能为空'))
              } else {
                  const reg = /^([+]\d+[.]\d+|[-]\d+[.]\d+|\d+[.]\d+|[+]\d+|[-]\d+|\d+)$/gi　　　　　　//数字开始，数字结束
                  const dataArr = (this.landForm.landArea + "").match(reg)
                  if (dataArr == null || dataArr.length == 0) {
                      callback(new Error('地块面积格式错误'))
                  }
                  callback()
              }
          }
          return {
              saveStatus:false,
              mainCardHeight: 0,
              innerVisible: false,
              emptyImg: require("@/assets/img/land/daihuoqu.png"),
              backImg: require("@/assets/img/farm/goback.png"),
              formLabelWidth:"100px",
              landImg: require("@/assets/img/land/add_land.png"),
              landForm: {
                  planter:"",
                  patrol:"",
                  landName:"",
                  position:"",
                  landArea:"",
                  landType:"",
                  area:"",
                  imgUrl:""
              },
              landRules:{
                  landName: [
                      {required: true, message: '地块名称不能为空', trigger: 'blur'},
                      {min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur'}
                  ],
                  planter: [
                      { required: true, message: '请选择种植人员', trigger: 'change' }
                  ],
                  patrol: [
                      { required: true, message: '请选择巡田人员', trigger: 'change' }
                  ],
                  landType: [
                      { required: true, message: '请选择类型', trigger: 'change' }
                  ],
                  area: [
                      {required: true, message: '种植面积不能为空', trigger: 'blur'},
                      {validator: validateArea, trigger: 'blur'}
                  ],
                  landArea: [
                      {required: true, message: '地块面积不能为空', trigger: 'blur'},
                      {validator: validatelandArea, trigger: 'blur'}
                  ],
              },
              mapExtent:[],
              pointArray:[],
              landTypeOptions: [],
              patrolTypeOptions:[],
              plantersTypeOptions:[],
              map: null,
              image: null,
              raster: null,
              draw: null,
              snap: null,
              vector: null,
              source: null,
              genJson: null,
              imageData: null
          }
      },
      created(){
          this.getAllOptions()
          this.getLandInfo()
      },
      mounted(){
          this.landTypeOptions = [
              {typeCode:"T", typeName:"大田"},
              {typeCode:"P", typeName:"大棚"}
          ]
          this.$dynamic(
              window,
              document,
              186,
              (height) => {
                  this.mainCardHeight = height
              }
          );
          this.mapExtent = []
          this.pointArray = []
      },
      beforeDestroy() {
          this.$unResize(window)
      },
      methods: {
          onSubmit(){
              if(this.imageData==null){
                  this.$message({type:"info", message:"请划分地块"})
                  return
              }
              this.$refs.landForm.validate((valid) => {
                  if (valid) {
                      // this.saveStatus = true
                      const landForm = this.$cloneDeep(this.landForm)
                      const params = {
                          landName:landForm.landName, // 地块名称
                          landLocation:JSON.stringify(landForm.position), // 地块定位
                          landType:landForm.landType, //地块类型
                          landArea:landForm.landArea*1, // 地块面积
                          landImg:landForm.imgUrl, // 地块图片地址
                          plantPerson:landForm.planter, // 种植人员
                          patrolPerson:landForm.patrol, // 巡田人员
                          landAddress:landForm.area*1, //种植面积
                      }
                      console.log("params",params)
                      postFarmLand(params).then(response=>{
                          this.saveStatus = false
                          const {data, msg, code} = response.data
                          if(code==200){
                              this.$message.success(msg)
                              this.$emit("refresh")
                              this.$emit("changePage",1)
                          }else{
                              this.$message.error(msg)
                          }
                      }).catch(err=>{
                          this.saveStatus = false
                          this.$message.error(err)
                      })
                      this.saveStatus = false
                  }else{
                      console.log('error submit!!')
                      return false
                  }
              })
          },
          handleClickMap() {
              this.requestBaseMap()
              this.innerVisible = true
              this.$nextTick(() => {
                  this.initMap()
              })
          },
          requestBaseMap(){
              this.raster = new TileLayer({
                  source: new OSM(),
              });
              // TODO: ImageWMS 中url生产时需要替换成天地图
              this.image = new Image({
                  source: new ImageWMS({
                      //不能设置为0，否则地图不展示。
                      ratio: 1,
                      url: "http://8.130.53.217:8080/geoserver/xam/wms",
                      params: {
                          FORMAT: "image/jpeg",
                          VERSION: "1.1.1",
                          STYLES: "",
                          LAYERS: "xam:1",
                          exceptions: "application/vnd.ogc.se_inimage"
                      },
                      crossOrigin:"anonymous"
                  })
              });
          },
          initMap() {
              const _that = this
              // 鼠标圆点
              const raster = new TileLayer({
                  source: new OSM()
              });
              // 鼠标圆点
              this.source = new VectorSource();
              // 鼠标圆点
              this.vector = new Vector({
                  source: this.source,
                  style: new Style({
                      fill: new Fill({
                          color: 'transparent',
                      }),
                      stroke: new Stroke({
                          color: '#ffcc33',
                          width: 2,
                      }),
                      image: new CircleStyle({
                          radius: 7,
                          fill: new Fill({
                              color: '#ffcc33',
                          }),
                      }),
                  }),
              });

              const baseStyle = new Style({
                  fill: new Fill({
                      color: "rgba(117,255,30,0.3)"
                  }),
                  stroke: new Stroke({
                      color: "#75ff1e",
                      width: 3
                  })
              })

              let zoom = 0;
              if (window.screen.availWidth == 3840) {
                  zoom = 18.6;
              } else if (window.screen.availWidth == 2560) {
                  zoom = 18;
              } else if (window.screen.availWidth == 1920) {
                  zoom = 17.6;
              } else if (window.screen.availWidth == 1600) {
                  zoom = 17.34;
              } else if (window.screen.availWidth == 1366) {
                  zoom = 17.1;
              } else {
                  zoom = 17.6;
              }
              this.map = new Map({
                  //地图容器ID
                  target: "mapLandDiv",
                  //引入地图
                  layers: [raster, this.image, this.vector],
                  view: new View({
                      //地图中心点
                      center: fromLonLat([121.8833790906, 44.7467653]),
                      // zoom: 17.6,
                      // minZoom:17.6 // 地图缩放最小级别
                      zoom: zoom,
                      minZoom: 17, // 地图缩放最小级别
                      maxZoom: 19,
                      mouseWheelZoom: false,
                      // extent: fromLonLat(extend)//transformExtent(fromLonLat(), 'EPSG:4326', 'EPSG:3857')
                  }),
                  crossOrigin:"anonymous"
              });
              this.addInteractions()

              this.map.on('singleclick', (e) => {
                  console.log("点击了",e.coordinate)
                  this.pointArray.push(e.coordinate)
                  this.landForm.position = this.$cloneDeep(this.pointArray)
              })
              // console.log("获取当前地图窗口的坐标系统",this.map.getView().getProjection())
              // 删除默认的双击事件
              const dblClickInteraction = this.map
                  .getInteractions()
                  .getArray()
                  .find(interaction => {
                      return interaction instanceof DoubleClickZoom;
                  });
              this.map.removeInteraction(dblClickInteraction);
              // 删除默认的拖拽事件
              // const dragInteraction = this.map
              //     .getInteractions()
              //     .getArray()
              //     .find(interaction => {
              //         return interaction instanceof DragPan;
              //     });
              // this.map.removeInteraction(dragInteraction);

              //删除默认滑轮
              const zoomInteraction = this.map
                  .getInteractions()
                  .getArray()
                  .find(interaction => {
                      return interaction instanceof MouseWheelZoom;
                  });
              this.map.removeInteraction(zoomInteraction);
          },
          async getAllOptions(){
              this.plantersTypeOptions = []
              this.patrolTypeOptions = []
              const responses = await Promise.all([queryPlanters(), queryWatchPlanters()])
              if(responses[0].data.code==200){
                  if(responses[0].data.data && responses[0].data.data.length>0){
                      this.plantersTypeOptions = responses[0].data.data.map(item=>{
                          return {
                              planterCode: item.userId,
                              planterName: item.userName
                          }
                      })
                  }
              }
              if(responses[1].data.code==200){
                  if(responses[1].data.data && responses[1].data.data.length>0){
                      this.patrolTypeOptions = responses[1].data.data.map(item=>{
                          return {
                              patrolCode: item.userId,
                              patrolName: item.userName
                          }
                      })
                  }
              }
          },
          async getLandInfo() {
              this.imageData = null
              const response = await getLandProperties()
              const {msg} = response.data
              this.genJson = msg
          },
          //向内修改范围
          getXDis(e, number) {
              let min = undefined;
              let max = undefined;
              e.forEach(element => {
                  if (min == undefined || element[number] < min) {
                      min = element[number];
                  }
                  if (max == undefined || element[number] > max) {
                      max = element[number];
                  }
              });
              return [min+2, max - min-4];
          },
          addInteractions() {
              this.draw = new Draw({
                  source: this.source,
                  type: "Polygon",
              });
              const _that = this
              this.map.addInteraction(this.draw);
              this.snap = new Snap({source: this.source});
              this.map.addInteraction(this.snap);
              const projection = get('EPSG:4326');
              this.draw.on('drawend', res => {
                  // 获取屏幕上画矩形，然后获取矩形经纬度坐标
                  this.map.once('postrender', function(e) {
                      _that.mapExtent = [];
                      _that.pointArray.forEach(item=>{
                          _that.mapExtent.push(e.target.getPixelFromCoordinate(item))
                      })
                      // console.log("extent",this.mapExtent, e)
                  })
                  //获取绘制图形的面积
                  const size = getArea(res.feature.geometryChangeKey_.target, {
                      projection: projection,
                      radius: 16//'6371004',
                  });
                  //TODO:需要计算选取的图形面积，需要提供比例
                  console.log("图形的面积,需要计算成亩",size)

                  this.$confirm('确定要保存划分的地块吗?', '提示', {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning'
                  }).then(() => {
                      this.pointArray = []
                      const canvas = document.getElementById("mapLandDiv").getElementsByTagName("canvas")[0]
                      this.map.once('rendercomplete', function(event) {
                          // console.log("rendercomplete", event)
                          const x_dx = _that.getXDis(_that.mapExtent, 0);
                          const y_dy = _that.getXDis(_that.mapExtent, 1);
                          var ctx = canvas.getContext("2d");
                          const image = ctx.getImageData(x_dx[0], y_dy[0], x_dx[1]+180, y_dy[1]+100);
                          _that.imageData = image;
                          let targetCanvas = document.getElementById("target_map_canvas")
                          let tmpCtx=targetCanvas.getContext("2d")
                          tmpCtx.clearRect(0,0,targetCanvas.width,targetCanvas.height);
                          tmpCtx.putImageData(_that.imageData, 0, 0)
                          _that.uploadImg(_that.dataURLtoBlob(targetCanvas.toDataURL()))
                      });
                      this.map.renderSync();
                      this.landForm.area = size
                      this.innerVisible = false
                  }).catch(() => {
                      this.pointArray = []
                      this.imageData = null
                      this.source.clear()
                  });
              })
          },
          uploadImg(imgFile){
              const formData = new FormData();
              formData.append("file", imgFile)
              upload(formData).then(res => {
                  if (res.data.code == 200) {
                      // this.landForm.imgUrl = res.data.data.url + res.data.data.path
                      this.landForm.imgUrl = res.data.data.path
                  }
              }).catch(err => {
                  console.log(err)
                  this.$message({type: 'error', message: "上传异常:" + err})
              })
          },
          dataURLtoBlob(dataurl) {
              var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                  bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
              while (n--) {
                  u8arr[n] = bstr.charCodeAt(n);
              }
              return new Blob([u8arr], { type: mime });
          },
          handleClickBack() {
              this.$emit("changePage", 1)
          }
      }
  }
</script>
<style>
  .ol-uncollapsible {
    display: none;
  }
</style>
<style scoped>
  .flex-wrap {
    display: flex;
    align-items: center;
  }

  .go-back {
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px 10px;
    width: 80px;
    background: #f1faf7;
  }
  .land-add-button{
    width: 47%;
    display: flex;
    align-items: center;
    justify-content: center;
    height:32px;
    line-height:32px;
    background: #b2e1d1;
    border-radius: 4px;
    color: #0f6a4b;
    cursor: pointer;
  }
  .land-add-button img {
    width: 16px;
    height: 16px;
    margin-right: 10px;
  }
  .land-preview-container{
    border: 1px solid #c0c4cc;
    border-radius: 4px;
    width: 100%;
    user-select: none;
    position: relative;
  }
  .canvas-wrap{
    user-select: none;
    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  .land-preview-img{
    user-select: none;
    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%, -50%);
    user-select: none;
  }
  .land-preview-text{
    user-select: none;
    position: absolute;
    top:70%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
</style>
